package castle.defense.project;

import java.util.HashMap;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;
/**
 * Main sound manager class.
 * Basic sound playing functionality
 * 
 * 
 * Needs background music function, to automatically loop the background music.
 *  (This function may need to be in the main class as that is the only thread with time update, or just
 *   add an update function to this).
 * @author Daniel Wasserman
 *
 */
public class SoundManager {
	public static int slam = 1251, shatter = 14231, gun = 77894, bow = 1561251;
	//Sound pool to actually play the sounds
	private static SoundPool mSoundPool;
	//HashMap of the indices to sounds
	private static HashMap<Integer, Integer> mSoundPoolMap;
	//Audio manager
	private static AudioManager mAudioManager;
	private static Context mContext;
	private static MediaPlayer backGround;
	private static int currentBackground=-1;
	/**
	 * @param theContext The context that this SoundManager class will operate in.
	 * 
	 * Function to initialize the sound manager.
	 */
	public static void initializeSoundManager(Context theContext)
	{
		mContext = theContext;

		mSoundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);

		mSoundPoolMap = new HashMap<Integer, Integer>();

		mAudioManager = (AudioManager)mContext.getSystemService(Context.AUDIO_SERVICE);
		
		addSound(SoundManager.shatter, R.raw.glass_shatter);
		addSound(SoundManager.bow, R.raw.bow1);
		addSound(SoundManager.gun, R.raw.gun1);
		addSound(SoundManager.slam, R.raw.slam1);
	}

	/**
	 * 
	 * @param index The index of the sound that is being added to the map.
	 * @param SoundID The ID of the sound being added from R.raw.file_name_here
	 * 
	 * This function will return true if the sound was properly added, and false if the index
	 * is currently in use and could not be used.
	 */

	public static boolean addSound(int index, int SoundID)
	{
		if(mSoundPoolMap.containsKey(index))
			return false;
		mSoundPoolMap.put(index, mSoundPool.load(mContext, SoundID, 1));
		return true;
	}

	/**
	 * 
	 * @param index the index of the sound to be played
	 * 
	 */
	public static void playSound(int index)
	{
		if(!Options.soundOn())
			return;
		float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
		streamVolume = streamVolume / (2*mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
		mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, 0, 1f);
	}

	/**
	 * Function that stops a sound currently being played 
	 * 
	 * @param index the index of the music or sound to stop being played
	 */
	public static void stopSound(int index) {
		mSoundPool.stop(mSoundPoolMap.get(index));
	}

	/**
	 * A simple loop function that will loop background music.
	 * 
	 * @param index The index of the music to be looped.
	 */
	public static void loopSound(int index) {
		float streamVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
		streamVolume = streamVolume / mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
		mSoundPool.play(mSoundPoolMap.get(index), streamVolume, streamVolume, 1, -1, 1f);
	}

	public static void setBackground(int id) {
		if(!Options.soundOn())
			return;
		if(currentBackground == id) {
			resumeBackground();
			return;
		}
		stopBackground();
		currentBackground = id;
		backGround = MediaPlayer.create(mContext, id);
		backGround.setLooping(true);
		backGround.start();
	}

	public static void stopBackground() {
		if(backGround!=null) {
			currentBackground = -1;
			if(backGround.isPlaying()) {
				backGround.stop();
			}
			backGround.release();
			backGround = null;
		}
	}

	public static void pauseBackground() {
		if(backGround!=null && backGround.isPlaying())
			backGround.pause();
	}

	public static boolean resumeBackground() {
		if(Options.soundOn() && backGround!=null && !backGround.isPlaying()) {
			backGround.start();
			return true;
		}
		return false;
	}
}
